import 'package:flutter/material.dart';

void main() {
  runApp(const BouncingBallApp());
}

class BouncingBallApp extends StatelessWidget {
  const BouncingBallApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '弹跳小球动画',
      theme: ThemeData(primarySwatch: Colors.blue, useMaterial3: true),
      home: const BouncingBallScreen(),
    );
  }
}

class BouncingBallScreen extends StatefulWidget {
  const BouncingBallScreen({super.key});

  @override
  State<BouncingBallScreen> createState() => _BouncingBallScreenState();
}

class _BouncingBallScreenState extends State<BouncingBallScreen>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;

  // 小球弹跳的曲线 - 使用弹性曲线模拟真实弹跳
  final Curve _bounceCurve = Curves.elasticOut;

  // 小球属性
  final double _ballSize = 60.0;
  final Color _ballColor = Colors.redAccent;

  @override
  void initState() {
    super.initState();

    // 初始化动画控制器，设置动画持续时间
    _controller = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 1500),
    );

    // 创建从0到1的动画，应用弹跳曲线
    _animation = Tween<double>(
      begin: 0.0,
      end: 1.0,
    ).animate(CurvedAnimation(parent: _controller, curve: _bounceCurve));

    // 开始动画并循环播放
    _startAnimation();
  }

  void _startAnimation() {
    _controller.reset();
    _controller.forward();
  }

  void _toggleAnimation() {
    if (_controller.isAnimating) {
      _controller.stop();
    } else {
      _startAnimation();
    }
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('弹跳小球动画'),
        backgroundColor: Colors.blue,
        foregroundColor: Colors.white,
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            // 小球容器
            Container(
              width: 200,
              height: 300,
              decoration: BoxDecoration(
                border: Border.all(color: Colors.grey),
                borderRadius: BorderRadius.circular(10),
              ),
              child: AnimatedBuilder(
                animation: _animation,
                builder: (context, child) {
                  // 计算小球位置
                  // 使用正弦函数模拟弹跳轨迹
                  double bounceHeight = 250.0;
                  double bounceProgress = _animation.value;

                  // 小球Y坐标计算
                  double yPosition = bounceHeight * (1 - bounceProgress);

                  return Stack(
                    children: [
                      // 地面
                      Positioned(
                        bottom: 0,
                        left: 0,
                        right: 0,
                        child: Container(height: 5, color: Colors.grey[400]),
                      ),
                      // 小球
                      Positioned(
                        left: 100 - _ballSize / 2,
                        top: yPosition,
                        child: Container(
                          width: _ballSize,
                          height: _ballSize,
                          decoration: BoxDecoration(
                            color: _ballColor,
                            shape: BoxShape.circle,
                            boxShadow: [
                              BoxShadow(
                                color: Colors.black.withOpacity(0.3),
                                blurRadius: 8,
                                offset: const Offset(0, 4),
                              ),
                            ],
                          ),
                        ),
                      ),
                    ],
                  );
                },
              ),
            ),

            const SizedBox(height: 30),

            // 控制按钮
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                ElevatedButton(
                  onPressed: _toggleAnimation,
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.blue,
                    foregroundColor: Colors.white,
                  ),
                  child: AnimatedBuilder(
                    animation: _controller,
                    builder: (context, child) {
                      return Text(_controller.isAnimating ? '暂停' : '开始');
                    },
                  ),
                ),

                const SizedBox(width: 20),

                ElevatedButton(
                  onPressed: _startAnimation,
                  style: ElevatedButton.styleFrom(
                    backgroundColor: Colors.green,
                    foregroundColor: Colors.white,
                  ),
                  child: const Text('重新开始'),
                ),
              ],
            ),

            const SizedBox(height: 20),

            // 动画说明
            Container(
              padding: const EdgeInsets.all(16),
              margin: const EdgeInsets.symmetric(horizontal: 20),
              decoration: BoxDecoration(
                color: Colors.blue[50],
                borderRadius: BorderRadius.circular(10),
              ),
              child: const Text(
                '这个动画模拟了小球从高处落下并弹跳的效果。'
                '使用了弹性曲线(Curves.elasticOut)来模拟真实的弹跳物理效果。',
                textAlign: TextAlign.center,
                style: TextStyle(fontSize: 14, color: Colors.blueGrey),
              ),
            ),
          ],
        ),
      ),
    );
  }
}
